using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
using ICSharpCode.TextEditor.Properties;

namespace ICSharpCode.TextEditor
{
    public class TextEditorScrollBarRenderer
    {
        protected bool drawThumbGrip = true;

        protected Color[,] thumbColors = new Color[3, 8];

        protected Color[,] arrowColors = new Color[3, 8];

        protected Color[] arrowBorderColors = new Color[4];

        protected Color[] backgroundColors = new Color[5];

        protected Color[] trackColors = new Color[2];

        internal TextEditorScrollBarRenderer()
        {
            drawThumbGrip = true;
            thumbColors[0, 0] = Color.FromArgb(96, 111, 148);
            thumbColors[0, 1] = Color.FromArgb(232, 233, 233);
            thumbColors[0, 2] = Color.FromArgb(230, 233, 241);
            thumbColors[0, 3] = Color.FromArgb(233, 237, 242);
            thumbColors[0, 4] = Color.FromArgb(209, 218, 228);
            thumbColors[0, 5] = Color.FromArgb(218, 227, 235);
            thumbColors[0, 6] = Color.FromArgb(190, 202, 219);
            thumbColors[0, 7] = Color.FromArgb(96, 11, 148);
            thumbColors[1, 0] = Color.FromArgb(60, 110, 176);
            thumbColors[1, 1] = Color.FromArgb(187, 204, 228);
            thumbColors[1, 2] = Color.FromArgb(205, 227, 254);
            thumbColors[1, 3] = Color.FromArgb(252, 253, 255);
            thumbColors[1, 4] = Color.FromArgb(170, 207, 247);
            thumbColors[1, 5] = Color.FromArgb(219, 232, 251);
            thumbColors[1, 6] = Color.FromArgb(190, 202, 219);
            thumbColors[1, 7] = Color.FromArgb(233, 233, 235);
            thumbColors[2, 0] = Color.FromArgb(60, 110, 176);
            thumbColors[2, 1] = Color.FromArgb(187, 204, 228);
            thumbColors[2, 2] = Color.FromArgb(205, 227, 254);
            thumbColors[2, 3] = Color.FromArgb(252, 253, 255);
            thumbColors[2, 4] = Color.FromArgb(170, 207, 247);
            thumbColors[2, 5] = Color.FromArgb(219, 232, 251);
            thumbColors[2, 6] = Color.FromArgb(190, 202, 219);
            thumbColors[2, 7] = Color.FromArgb(233, 233, 235);
            arrowColors[0, 0] = Color.FromArgb(223, 236, 252);
            arrowColors[0, 1] = Color.FromArgb(207, 225, 248);
            arrowColors[0, 2] = Color.FromArgb(245, 249, 255);
            arrowColors[0, 3] = Color.FromArgb(237, 244, 252);
            arrowColors[0, 4] = Color.FromArgb(244, 249, 255);
            arrowColors[0, 5] = Color.FromArgb(244, 249, 255);
            arrowColors[0, 6] = Color.FromArgb(251, 253, 255);
            arrowColors[0, 7] = Color.FromArgb(251, 253, 255);
            arrowColors[1, 0] = Color.FromArgb(205, 222, 243);
            arrowColors[1, 1] = Color.FromArgb(186, 208, 235);
            arrowColors[1, 2] = Color.FromArgb(238, 244, 252);
            arrowColors[1, 3] = Color.FromArgb(229, 237, 247);
            arrowColors[1, 4] = Color.FromArgb(223, 234, 247);
            arrowColors[1, 5] = Color.FromArgb(241, 246, 254);
            arrowColors[1, 6] = Color.FromArgb(243, 247, 252);
            arrowColors[1, 7] = Color.FromArgb(250, 252, 255);
            arrowColors[2, 0] = Color.FromArgb(215, 220, 225);
            arrowColors[2, 1] = Color.FromArgb(195, 202, 210);
            arrowColors[2, 2] = Color.FromArgb(242, 244, 245);
            arrowColors[2, 3] = Color.FromArgb(232, 235, 238);
            arrowColors[2, 4] = Color.FromArgb(226, 228, 230);
            arrowColors[2, 5] = Color.FromArgb(230, 233, 236);
            arrowColors[2, 6] = Color.FromArgb(244, 245, 245);
            arrowColors[2, 7] = Color.FromArgb(245, 247, 248);
            backgroundColors[0] = Color.FromArgb(235, 237, 239);
            backgroundColors[1] = Color.FromArgb(252, 252, 252);
            backgroundColors[2] = Color.FromArgb(247, 247, 247);
            backgroundColors[3] = Color.FromArgb(238, 238, 238);
            backgroundColors[4] = Color.FromArgb(240, 240, 240);
            trackColors[0] = Color.FromArgb(204, 204, 204);
            trackColors[1] = Color.FromArgb(220, 220, 220);
            arrowBorderColors[0] = Color.FromArgb(135, 146, 160);
            arrowBorderColors[1] = Color.FromArgb(140, 151, 165);
            arrowBorderColors[2] = Color.FromArgb(128, 139, 153);
            arrowBorderColors[3] = Color.FromArgb(99, 110, 125);
        }

        public virtual void DrawBorder(Graphics g, bool enable, Color color, Rectangle rect)
        {
            ControlPaint.DrawBorder(g, rect, color, ButtonBorderStyle.Solid);
        }

        public virtual void DrawBackground(Graphics g, Rectangle rect, ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (!rect.IsEmpty && !g.IsVisibleClipEmpty && g.VisibleClipBounds.IntersectsWith(rect))
            {
                if (orientation == ScrollBarOrientation.Vertical)
                {
                    DrawBackgroundVertical(g, rect);
                }
                else
                {
                    DrawBackgroundHorizontal(g, rect);
                }
            }
        }

        public virtual void DrawTrack(Graphics g, Rectangle rect, ScrollBarState state, ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (rect.Width > 0 && rect.Height > 0 && state == ScrollBarState.Pressed && !g.IsVisibleClipEmpty && g.VisibleClipBounds.IntersectsWith(rect))
            {
                if (orientation == ScrollBarOrientation.Vertical)
                {
                    DrawTrackVertical(g, rect);
                }
                else
                {
                    DrawTrackHorizontal(g, rect);
                }
            }
        }

        public virtual void DrawThumb(Graphics g, Rectangle rect, ScrollBarState state, ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (!rect.IsEmpty && !g.IsVisibleClipEmpty && g.VisibleClipBounds.IntersectsWith(rect) && state != ScrollBarState.Disabled)
            {
            }
        }

        public virtual void DrawThumbGrip(Graphics g, Rectangle rect, ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (rect.IsEmpty || g.IsVisibleClipEmpty || !g.VisibleClipBounds.IntersectsWith(rect) || !drawThumbGrip)
            {
                return;
            }
            using (Image image = Resources.GripNormal)
            {
                Rectangle destRect = AdjustThumbGrip(rect, orientation, image);
                using (ImageAttributes imageAttributes = new ImageAttributes())
                {
                    imageAttributes.SetColorMatrix(new ColorMatrix(new float[5][]
                    {
                        new float[5] { 1f, 0f, 0f, 0f, 0f },
                        new float[5] { 0f, 1f, 0f, 0f, 0f },
                        new float[5] { 0f, 0f, 1f, 0f, 0f },
                        new float[5] { 0f, 0f, 0f, 0.8f, 0f },
                        new float[5] { 0f, 0f, 0f, 0f, 1f }
                    }), ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                    g.DrawImage(image, destRect, 0, 0, destRect.Width, destRect.Height, GraphicsUnit.Pixel, imageAttributes);
                }
            }
        }

        public virtual void DrawArrowButton(Graphics g, Rectangle rect, ScrollBarArrowButtonState state, bool arrowUp, ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (!rect.IsEmpty && !g.IsVisibleClipEmpty && g.VisibleClipBounds.IntersectsWith(rect))
            {
                if (orientation == ScrollBarOrientation.Vertical)
                {
                    DrawArrowButtonVertical(g, rect, state, arrowUp);
                }
                else
                {
                    DrawArrowButtonHorizontal(g, rect, state, arrowUp);
                }
            }
        }

        protected void DrawBackgroundVertical(Graphics g, Rectangle rect)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(rect, backgroundColors[3], backgroundColors[4], LinearGradientMode.Horizontal))
            {
                g.FillRectangle(brush, rect);
            }
        }

        protected void DrawBackgroundHorizontal(Graphics g, Rectangle rect)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(rect, backgroundColors[3], backgroundColors[4], LinearGradientMode.Vertical))
            {
                g.FillRectangle(brush, rect);
            }
        }

        protected void DrawTrackVertical(Graphics g, Rectangle rect)
        {
            Rectangle rect2 = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
            using (LinearGradientBrush brush = new LinearGradientBrush(rect2, trackColors[0], trackColors[1], LinearGradientMode.Horizontal))
            {
                g.FillRectangle(brush, rect2);
            }
        }

        protected void DrawTrackHorizontal(Graphics g, Rectangle rect)
        {
            Rectangle rect2 = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
            using (LinearGradientBrush brush = new LinearGradientBrush(rect2, trackColors[0], trackColors[1], LinearGradientMode.Vertical))
            {
                g.FillRectangle(brush, rect2);
            }
        }

        protected Rectangle AdjustThumbGrip(Rectangle rect, ScrollBarOrientation orientation, Image gripImage)
        {
            Rectangle result = rect;
            checked
            {
                if (orientation == ScrollBarOrientation.Vertical)
                {
                    result.X += unchecked(result.Width / 2) - unchecked(gripImage.Width / 2);
                    result.Y += unchecked(result.Height / 2) - unchecked(gripImage.Height / 2);
                }
                else
                {
                    gripImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    result.X += unchecked(result.Width / 2) - unchecked(gripImage.Width / 2);
                    result.Y += unchecked(result.Height / 2) - unchecked(gripImage.Height / 2);
                }
                result.Width = gripImage.Width;
                result.Height = gripImage.Height;
                return result;
            }
        }

        protected void DrawThumbVertical(Graphics g, Rectangle rect, ScrollBarState state)
        {
            int num = 0;
            switch (state)
            {
                case ScrollBarState.Hot:
                    num = 1;
                    break;
                case ScrollBarState.Pressed:
                    num = 2;
                    break;
            }
            float radius = 0f;
            Rectangle rectangle = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
            if (num == 0)
            {
                using (LinearGradientBrush brush = new LinearGradientBrush(rectangle, thumbColors[num, 4], thumbColors[num, 5], LinearGradientMode.Horizontal))
                {
                    g.FillRectangle(brush, rect);
                }
            }
            else
            {
                using (LinearGradientBrush brush2 = new LinearGradientBrush(rectangle, thumbColors[num, 4], thumbColors[num, 5], LinearGradientMode.Horizontal))
                {
                    g.FillRectangle(brush2, rect);
                }
            }
            g.SmoothingMode = SmoothingMode.AntiAlias;
            using (Pen pen = new Pen(thumbColors[num, 0]))
            {
                using (GraphicsPath path = CreateRoundPath(rectangle, radius))
                {
                    g.DrawPath(pen, path);
                }
            }
            g.SmoothingMode = SmoothingMode.None;
        }

        protected void DrawThumbHorizontal(Graphics g, Rectangle rect, ScrollBarState state)
        {
            int num = 0;
            switch (state)
            {
                case ScrollBarState.Hot:
                    num = 1;
                    break;
                case ScrollBarState.Pressed:
                    num = 2;
                    break;
            }
            float radius = 0f;
            Rectangle rectangle = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
            if (num == 0)
            {
                using (LinearGradientBrush brush = new LinearGradientBrush(rectangle, thumbColors[num, 4], thumbColors[num, 5], LinearGradientMode.Vertical))
                {
                    g.FillRectangle(brush, rectangle);
                }
            }
            else
            {
                using (LinearGradientBrush brush2 = new LinearGradientBrush(rectangle, thumbColors[num, 4], thumbColors[num, 5], LinearGradientMode.Vertical))
                {
                    g.FillRectangle(brush2, rectangle);
                }
            }
            g.SmoothingMode = SmoothingMode.AntiAlias;
            using (Pen pen = new Pen(thumbColors[num, 0]))
            {
                using (GraphicsPath path = CreateRoundPath(rectangle, radius))
                {
                    g.DrawPath(pen, path);
                }
            }
            g.SmoothingMode = SmoothingMode.None;
        }

        protected void DrawArrowButtonVertical(Graphics g, Rectangle rect, ScrollBarArrowButtonState state, bool arrowUp)
        {
            using (Image image = GetArrowDownButtonImage(state))
            {
                if (arrowUp)
                {
                    image.RotateFlip(RotateFlipType.Rotate180FlipNone);
                }
                g.DrawImage(image, rect);
            }
        }

        protected void DrawArrowButtonHorizontal(Graphics g, Rectangle rect, ScrollBarArrowButtonState state, bool arrowUp)
        {
            using (Image image = GetArrowDownButtonImage(state))
            {
                if (arrowUp)
                {
                    image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                }
                else
                {
                    image.RotateFlip(RotateFlipType.Rotate270FlipNone);
                }
                g.DrawImage(image, rect);
            }
        }

        protected Image GetArrowDownButtonImage(ScrollBarArrowButtonState state)
        {
            Rectangle rect = new Rectangle(0, 0, 15, 17);
            Bitmap bitmap = new Bitmap(15, 17, PixelFormat.Format32bppArgb);
            bitmap.SetResolution(72f, 72f);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.SmoothingMode = SmoothingMode.None;
                graphics.InterpolationMode = InterpolationMode.Low;
                int num = -1;
                switch (state)
                {
                    case ScrollBarArrowButtonState.UpHot:
                    case ScrollBarArrowButtonState.DownHot:
                        num = 1;
                        break;
                    case ScrollBarArrowButtonState.UpActive:
                    case ScrollBarArrowButtonState.DownActive:
                        num = 0;
                        break;
                    case ScrollBarArrowButtonState.UpPressed:
                    case ScrollBarArrowButtonState.DownPressed:
                        num = 2;
                        break;
                }
                if (num != -1)
                {
                    using (LinearGradientBrush brush = new LinearGradientBrush(rect, arrowColors[num, 4], arrowColors[num, 5], LinearGradientMode.Vertical))
                    {
                        graphics.FillRectangle(brush, rect);
                    }
                }
                using (Image image = Resources.ScrollBarArrowDown)
                {
                    if (state == ScrollBarArrowButtonState.DownDisabled || state == ScrollBarArrowButtonState.UpDisabled)
                    {
                        ControlPaint.DrawImageDisabled(graphics, image, 3, 6, Color.Transparent);
                    }
                    else
                    {
                        graphics.DrawImage(image, 3, 6);
                    }
                }
            }
            return bitmap;
        }

        protected GraphicsPath CreateRoundPath(Rectangle r, float radius)
        {
            GraphicsPath graphicsPath = new GraphicsPath();
            if (radius > 0f)
            {
                graphicsPath.AddArc(r.X, r.Y, radius, radius, 180f, 90f);
                graphicsPath.AddArc((float)r.Width - radius, r.Y, radius, radius, 270f, 90f);
                graphicsPath.AddArc((float)r.Width - radius, (float)r.Height - radius, radius, radius, 0f, 90f);
                graphicsPath.AddArc(r.X, (float)r.Height - radius, radius, radius, 90f, 90f);
            }
            else
            {
                graphicsPath.AddRectangle(new RectangleF(r.X, r.Y, r.Width, r.Height));
            }
            graphicsPath.CloseFigure();
            return graphicsPath;
        }
    }
}
